package com.openlogic.logic.service.logic.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.query.QueryWrapper;
import com.openlogic.api.logic.dto.RuleModelDto;
import com.openlogic.api.logic.dto.RuleSqlModelDto;
import com.openlogic.api.logic.entity.RuleModel;
import com.openlogic.api.logic.entity.RuleModelNodeMerge;
import com.openlogic.api.logic.entity.RuleSqlModelColumn;
import com.openlogic.api.logic.entity.table.Tables;
import com.openlogic.api.logic.enums.RuleParamCategoryEnums;
import com.openlogic.common.core.exception.ServiceException;
import com.openlogic.common.core.utils.DateUtils;
import com.openlogic.common.logic.constants.RuleConstants;
import com.openlogic.common.security.utils.SecurityUtil;
import com.openlogic.logic.mapper.logic.RuleModelMapper;
import com.openlogic.logic.mapper.logic.RuleSqlModelColumnMapper;
import com.openlogic.logic.service.datasource.SqlConsoleService;
import com.openlogic.logic.service.logic.RuleModelNodeMergeService;
import com.openlogic.logic.service.logic.RuleModelService;

/**
 * @ClassName: RuleModelServiceImpl
 * @Description: 规则变量ServiceImpl
 * @author weiyongpeng
 * @date 2024年7月14日 上午10:42:56
 */
@Component
public class RuleModelServiceImpl implements RuleModelService {

	private static final Logger logger = LoggerFactory.getLogger(RuleModelServiceImpl.class);

	@Inject
	private RuleModelMapper ruleModelMapper;

	@Inject
	private RuleSqlModelColumnMapper ruleSqlModelColumnMapper;

	@Inject
	private RuleModelNodeMergeService ruleModelNodeMergeService;

	@Inject
	private SqlConsoleService sqlConsoleService;

	@Override
	public List<Map<String, Object>> listByCommonRuleParams(Map<String, Object> params) {
		// 私有参数查询自己的
		params.put("myCreate", String.valueOf(SecurityUtil.getUserId()));
		return ruleModelMapper.findCommonRuleParams(params);
	}

	@Override
	public List<RuleModel> findRuleParamForH(Map<String, Object> params) {
		// 私有参数查询自己的
		params.put("myCreate", String.valueOf(SecurityUtil.getUserId()));
		return ruleModelMapper.findRuleParamForH(params);
	}

	@Override
	public List<Map<String, Object>> listByDebugRuleParams(Map<String, Object> params) {
		return ruleModelMapper.findByDebugRuleParams(params);
	}

	@Override
	public List<RuleModelDto> listRuleDesignParam(Map<String, Object> params) {
		return ruleModelMapper.findRuleDesignParam(params);
	}

	@Override
	public List<RuleModel> listByRuleKey(RuleModel ruleModel) {
		return ruleModelMapper.selectListByQuery(
				QueryWrapper.create().where(Tables.ruleModel.ruleModelId.eq(ruleModel.getRuleModelId())));
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<RuleModel> listByRuleModelId(String ruleModelId) {
		List<RuleModel> models = ruleModelMapper.findModelsByRuleId(ruleModelId);
		List<RuleModel> temp = models;
		List<RuleModel> listCommon = models.stream()
				.filter(x -> x.getModelCategory().equals("0") || x.getModelCategory().equals("2"))
				.collect(Collectors.toList());
		List<RuleModel> listSQL = new ArrayList<>();
		List<List<RuleModel>> resList = temp.stream().filter(x -> x.getModelCategory().equals("1")).map(model -> {
			List<RuleModel> list = new ArrayList<>();
			listSQL.add(model);
			String param = model.getSqlParam();
			if (StringUtils.isNotBlank(param) && !StringUtils.equals(param, "null")) {
				List<Map<String, String>> array = JSONObject.parseObject(param, List.class);
				List<RuleModel> ruleModel = array.stream().map(map -> {
					RuleModel res = new RuleModel();
					map.entrySet().forEach(entry -> {
						String key = entry.getKey();
						String value = entry.getValue();
						if (key.equals("label")) {
							res.setName(value);
						} else if (key.equals("type")) {
							res.setDataType(value);
						} else if (key.equals("key")) {
							res.setModelIdentify(value);
						}
						res.setId(model.getSqlDataSourceId());
						res.setModelType(model.getModelType());
						res.setModelCategory("3");
					});
					return res;
				}).collect(Collectors.toList());
				list.addAll(ruleModel);
			}
			return list;
		}).collect(Collectors.toList());
		List<RuleModel> listRes = new ArrayList<>();
		listRes.addAll(listCommon);
		listRes.addAll(listSQL);
		resList.stream().forEach(x -> {
			listRes.addAll(x);
		});
		return listRes;
	}

	@Override
	public RuleSqlModelDto findSqlParamByName(String sqlParamName) {
		return ruleModelMapper.findSqlParamByName(sqlParamName);
	}

	@Override
	public void insert(RuleModel ruleModel) {
		Date nowDate = DateUtils.getNowDate();
		// 如果中文名为空则使用英文唯一标识
		String titleName = ruleModel.getName() == null ? ruleModel.getModelIdentify() : ruleModel.getName();
		ruleModel.setId(nowDate.getTime() + ""); // 规则属性唯一id
		ruleModel.setName(titleName);
		ruleModel.setModelTitle(titleName);
		ruleModel.setCreateBy(String.valueOf(SecurityUtil.getUserId()));
		ruleModel.setCreateTime(nowDate);
		ruleModel.setUpdateTime(nowDate);
		ruleModelMapper.insert(ruleModel);
	}

	@Override
	public void insertRuleParam(RuleModel ruleModel) {
		Date nowDate = DateUtils.getNowDate();
		String id = nowDate.getTime() + "";
		// 校验变量是否存在
		if (this.checkIsExistsFact(ruleModel.getModelIdentify()) > 0L) {
			logger.error("[" + ruleModel.getModelIdentify() + "]已存在,添加失败");
			throw new ServiceException("[" + ruleModel.getModelIdentify() + "]已存在,添加失败");
		}
		try {
			// 如果中文名为空则使用英文唯一标识
			String titleName = ruleModel.getName() == null ? ruleModel.getModelIdentify() : ruleModel.getName();
			ruleModel.setId(id); // 规则属性唯一id
			ruleModel.setName(titleName);
			ruleModel.setModelTitle(titleName);
			ruleModel.setCreateBy(String.valueOf(SecurityUtil.getUserId()));
			ruleModel.setCreateTime(nowDate);
			ruleModel.setUpdateTime(nowDate);
			ruleModel.setModelType((ruleModel.getModelCategory() != null
					&& (ruleModel.getModelCategory().equals("0") || ruleModel.getModelCategory().equals("2")))
							? ruleModel.getModelType()
							: "1");
			ruleModel.setDataType((ruleModel.getModelCategory() != null && ruleModel.getModelCategory().equals("0"))
					? ruleModel.getDataType()
					: "2");
			ruleModel.setIsNodeParam(RuleConstants.IS_NOT_NODE_PARAM);
			ruleModel.setSqlParam(JSON.toJSONString(ruleModel.getParam()));
			// 插入规则参数表
			ruleModelMapper.insert(ruleModel);
			// 如果是sql参数，还需要解析sql，插入sql决策参数属性明细表
			if (ruleModel.getModelCategory().equals(RuleParamCategoryEnums.SQL_PARAM.getCode())) {
				// 批量插入
				List<RuleSqlModelColumn> list = sqlConsoleService.parseSql(ruleModel);
				ruleSqlModelColumnMapper.insertBatch(list);
			}
		} catch (Exception e) {
			logger.error("新增异常,异常信息:{}", e.getMessage());
			throw new ServiceException("新增异常,新增失败!");
		}
	}

	@Override
	public void insertBatch(List<RuleModel> ruleModels) {
		ruleModelMapper.insertBatch(ruleModels);
	}

	@Override
	public void insertCommonParam(List<RuleModelNodeMerge> ruleModelNodeMergeDto) {
		try {
			ruleModelNodeMergeService.insertBatch(ruleModelNodeMergeDto);
		} catch (Exception e) {
			logger.error("公共参数引用异常,异常信息:{}", e.getMessage());
			throw new ServiceException("公共参数引用异常，新增失败!");
		}
	}

	@Override
	public void insertRuleDesignParam(RuleModel ruleModel) {
		Date nowDate = DateUtils.getNowDate();
		String id = nowDate.getTime() + "";
		// 校验变量是否存在
		if (this.checkIsExistsFact(ruleModel.getModelIdentify()) > 0L) {
			logger.error("[" + ruleModel.getModelIdentify() + "]已存在,添加失败");
			throw new ServiceException("[" + ruleModel.getModelIdentify() + "]已存在,添加失败");
		}
		try {
			// 如果中文名为空则使用英文唯一标识
			String titleName = ruleModel.getName() == null ? ruleModel.getModelIdentify() : ruleModel.getName();
			ruleModel.setId(id); // 规则属性唯一id
			ruleModel.setName(titleName);
			ruleModel.setModelTitle(titleName);
			ruleModel.setCreateBy(String.valueOf(SecurityUtil.getUserId()));
			ruleModel.setCreateTime(nowDate);
			ruleModel.setUpdateTime(nowDate);
			ruleModel.setModelType((ruleModel.getModelCategory() != null
					&& (ruleModel.getModelCategory().equals("0") || ruleModel.getModelCategory().equals("2")))
							? ruleModel.getModelType()
							: "1");
			ruleModel.setDataType((ruleModel.getModelCategory() != null && ruleModel.getModelCategory().equals("0"))
					? ruleModel.getDataType()
					: "2");
			ruleModel.setIsNodeParam(RuleConstants.IS_NODE_PARAM);
			ruleModel.setModelScopeType(RuleConstants.PRIVATE_PARAM);
			ruleModel.setSqlParam(JSON.toJSONString(ruleModel.getParam()));
			// 插入规则参数表
			ruleModelMapper.insert(ruleModel);

			// 如果是sql参数，还需要解析sql，插入sql决策参数属性明细表
			if (ruleModel.getModelCategory().equals(RuleParamCategoryEnums.SQL_PARAM.getCode())) {
				// 批量插入
				List<RuleSqlModelColumn> list = sqlConsoleService.parseSql(ruleModel);
				ruleSqlModelColumnMapper.insertBatch(list);
			}

			// 插入关联关系表
			RuleModelNodeMerge nodeMergeDto = new RuleModelNodeMerge();
			nodeMergeDto.setRuleFactId(id);
			nodeMergeDto.setNodeId(ruleModel.getNodeId());
			nodeMergeDto.setRuleId(ruleModel.getRuleModelId());
			nodeMergeDto.setModelScopeType(RuleConstants.PRIVATE_PARAM);
			// 插入关联关系表
			ruleModelNodeMergeService.save(nodeMergeDto);
		} catch (Exception e) {
			logger.error("新增异常,异常信息:{}", e.getMessage());
			throw new ServiceException("新增异常,新增失败!");
		}
	}

	@Override
	public void update(RuleModel ruleModel) {
		try {
			ruleModel.setUpdateBy(String.valueOf(SecurityUtil.getUserId()));
			ruleModel.setUpdateTime(DateUtils.getNowDate());
			ruleModel.setModelTitle(
					(ruleModel.getModelTitle() == null || ruleModel.getModelTitle().equals("")) ? ruleModel.getName()
							: ruleModel.getModelTitle());
			// 如果是私有参数则需要将isNodeParam设置为0，反之为1(不是节点参数)
			ruleModel.setIsNodeParam(
					(ruleModel.getModelScopeType().equals("1")) && !ruleModel.getIsNodeParam().equals("1") ? "0" : "1");
			// 如果是sql参数，还需要解析sql，插入sql决策参数属性明细表
			if (ruleModel.getModelCategory().equals(RuleParamCategoryEnums.SQL_PARAM.getCode())) {
				// 先删除sql参数列项
				ruleSqlModelColumnMapper.deleteByQuery(
						QueryWrapper.create().where(Tables.ruleSqlModelColumn.ruleFactId.eq(ruleModel.getId())));
				// 批量插入
				ruleModel.setSqlParam(JSON.toJSONString(ruleModel.getParam()));
				List<RuleSqlModelColumn> list = sqlConsoleService.parseSql(ruleModel);
				ruleSqlModelColumnMapper.insertBatch(list);
			}
			ruleModelMapper.updateByQuery(ruleModel,
					QueryWrapper.create().where(Tables.ruleModel.id.eq(ruleModel.getId())));
		} catch (Exception e) {
			logger.error("修改异常,异常信息:{}", e.getMessage());
			throw new ServiceException("修改异常,修改失败!");
		}
	}

	@Override
	public boolean delete(String ruleModeId) {
		try {
			if (ruleModelMapper.deleteByModelId(ruleModeId) > 0) {
				ruleSqlModelColumnMapper.deleteByQuery(
						QueryWrapper.create().where(Tables.ruleSqlModelColumn.ruleFactId.eq(ruleModeId)));
				return true;
			}
			return false;
		} catch (Exception e) {
			logger.error("删除失败：{}", e);
			throw new ServiceException("删除失败,请联系开发人员检查");
		}
	}

	@Override
	public boolean deleteByRuleKey(String ruleModelkey) {
		try {
			if (ruleModelMapper.deleteByModelKey(ruleModelkey) > 0) {
				return true;
			}
			return false;
		} catch (Exception e) {
			logger.error("删除失败：{}", e);
			throw new ServiceException("删除失败,请联系开发人员检查");
		}
	}

	@Override
	public boolean delete(RuleModel ruleMode) {
		// 如果是公共参数，只删除引用关系 否则需要删除参数
		if (ruleMode.getModelScopeType().equals(RuleConstants.PUBLIC_PARAM)
				|| (ruleMode.getModelScopeType().equals(RuleConstants.PRIVATE_PARAM)
						&& ruleMode.getIsNodeParam().equals(RuleConstants.IS_NOT_NODE_PARAM))) {
			// 删除引用关系
			boolean row = ruleModelNodeMergeService.remove(
					QueryWrapper.create().where(Tables.ruleModelNodeMerge.id.eq(ruleMode.getRuleModelNodeMergeId())));
			if (row) {
				ruleSqlModelColumnMapper.deleteByQuery(
						QueryWrapper.create().where(Tables.ruleSqlModelColumn.ruleFactId.eq(ruleMode.getId())));

				return true;
			}
		} else if (ruleMode.getModelScopeType().equals(RuleConstants.PRIVATE_PARAM)
				&& ruleMode.getIsNodeParam().equals(RuleConstants.IS_NODE_PARAM)) {
			// 1、删除引用关系
			ruleModelNodeMergeService.deleteByRuleKey(ruleMode.getRuleModelNodeMergeId());
			// 2、删除变量
			int ruleModelRow = ruleModelMapper.deleteByModelId(ruleMode.getId());
			// 3、删除sql参数列项
			ruleSqlModelColumnMapper.deleteByQuery(
					QueryWrapper.create().where(Tables.ruleSqlModelColumn.ruleFactId.eq(ruleMode.getId())));
			if (ruleModelRow > 0) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean deleteByNodeId(String nodeId) {
		ruleModelMapper.deleteByQuery(QueryWrapper.create().where(Tables.ruleModel.nodeId.eq(nodeId)));
		ruleModelNodeMergeService.deleteByNodeId(nodeId);
		return true;
	}

	@Override
	public int checkIsLinkModel(String ruleModeId) {
		return ruleModelMapper.checkIsLinkModel(ruleModeId);
	}

	@Override
	public Long checkIsExistsFact(String modelIdentify) {
		return ruleModelMapper
				.selectCountByQuery(QueryWrapper.create().where(Tables.ruleModel.modelIdentify.eq(modelIdentify)));
	}

	@Override
	public RuleModel checkRuleModel(RuleModel ruleModel, String type) {
		if (type.equals("update")) {
			return ruleModelMapper
					.selectOneByQuery(QueryWrapper.create().where(Tables.ruleModel.id.eq(ruleModel.getId())));
		}

		return ruleModelMapper.selectOneByQuery(
				QueryWrapper.create().where(Tables.ruleModel.id.eq(ruleModel.getId()).and(Tables.ruleModel.name
						.eq(ruleModel.getName()).or(Tables.ruleModel.modelIdentify.eq(ruleModel.getModelIdentify())))));
	}

}
